import sys
import subprocess
import argparse
import json
import os
import requests
from collections import defaultdict

send_url = "https://dcp.openharmony.cn/api/codecheckAccess/equipment/component/v1/save/component/duration"


class Ctime():
    def __init__(self, dur_time, sta_time, name, path):
        self.dur_time = dur_time
        self.sta_time = sta_time
        self.name =name
        self.path = path
        self.real_time = 0

def read_ohos_xml(ohos_xml):
    bundle_list = []
    with open(ohos_xml, 'r', encoding='utf-8') as file:
        lines = file.readlines()
        for line in lines:
            if 'path="' in line:  
                path_start = line.find('path="') + len('path="')
                path_end = line.find('"', path_start)
                path = line[path_start:path_end]
                bundle_list.append(path)
    bundle_list.append("moduletest/xts/modules")
    return bundle_list 

def get_gz_content(gz_file_path):
    output_file_path = gz_file_path[:-3]
    try:
        subprocess.run(f"gzip -cd {gz_file_path} > {output_file_path}", shell=True, check=True, stdout=subprocess.DEVNULL)
        with open(output_file_path, 'r') as file:
            content = file.read()
            tasks = json.loads(content)
            return tasks
    except subprocess.CalledProcessError as e:
        print(f"Error executing gzip: {e}")
        sys.exit(1)
    except Exception as e:
        print(f"An error occurred: {e}")
        sys.exit(1)

def get_compile_times(tasks, bundle_list, out_dir, product_name):
    tasks.sort(key=lambda x: x['ts'])
    path_durations = defaultdict(list)
    total_time = 0
    sum_time = 0
    for task in tasks:
        task['ts'] = int(task['ts'])
        task['dur'] = int(task['dur'])
        total_time += task['dur']
        sum_time = max(sum_time, task['ts'] + task['dur'])
    bundle_times = {}
    total_real_time = 0
    for task in tasks:
        task_name = task['name'].replace('thirdparty', 'third_party')
        task_path = next((b for b in bundle_list if (b in task_name or b.rsplit('/', 1)[-1] in task_name)), "")
        if not task_path:
            task_path = ""
        ctime = Ctime(task['dur'], task['ts'], task_name, task_path)
        ctime.real_time = max(ctime.dur_time * sum_time // total_time, 1)
        path_durations[task_path].append(ctime)
        if task_path in bundle_times:
            bundle_times[task_path] += ctime.real_time
        else:
            bundle_times[task_path] = ctime.real_time
        total_real_time += ctime.real_time
    sorted_items = sorted(bundle_times.items(), key=lambda item: item[1], reverse=True)
    data = []
    for key, value in sorted_items:
        compile_time = f"{value / 1000000:.3f}s"
        compile_time_ratio = f"{value / total_real_time * 100:.2f}%"
        data.append({
            "component_name": key,
            "compile_time": compile_time,
            "compile_time_ratio": compile_time_ratio
        })
    send_post_request(data, product_name)
    """
    out_json = os.path.join(out_dir, 'result_out.json')
    with open(out_json, 'w', encoding='utf-8') as file:
        json.dump(data, file, ensure_ascii=False, indent=4) 
    out_target = os.path.join(out_dir, 'target.txt')
    with open('target.txt', 'w', encoding='utf-8') as file:
        for path, tasks in path_durations.items():
            if path != "":
                continue
            for ctime in tasks:
                    file.write(f"  Task: {ctime.name}, Start: {ctime.sta_time}, Duration: {ctime.dur_time}, Real Time: {ctime.real_time}\n")
    """

def send_post_request(data, product_name):
    uuid = os.getenv('uuid')
    auth_info = os.getenv('auth_info')
    post_data = {
        "uuid": uuid,
        "component": product_name,
        "auth_info": auth_info,
        "data": data
    }
    print(post_data)
    response = requests.post(send_url, headers={'Content-Type': 'application/json'}, data=json.dumps(post_data), verify=False)
    if response.status_code == 200:
        print("success!")
        print(response.json())
    else:
        print(f"fail,code:{response.status_code}")
        print(response.text)

def main(args):
    parser = argparse.ArgumentParser()
    parser.add_argument('--build-trace', help='path to build trace')
    parser.add_argument('--ohos-xml', help='ohos.xml')
    parser.add_argument('--out-dir', help='out dir')
    parser.add_argument('--product-name', help='product name')
    options = parser.parse_args(args)
    if not os.path.exists(options.build_trace):
        return
    get_compile_times(get_gz_content(options.build_trace), read_ohos_xml(options.ohos_xml), options.out_dir, options.product_name)

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))

